#include <arch.h>
#include <kernel.h>
#include <trace.h>
#include <config.h>
#include <mm/mm.h>
#include <klibc/stdio.h>
#include <vfs/vfs.h>
#include <driver.h>
#include <device.h>
#include <shell.h>
#include "drivers/bus/pci/pci.h"

extern int pork_gui(int,int);

/* main function */ 
int 
main()
{
	uint16_t err;
	
	err = arch_init();
	
	if(err)
	{
		arch_shutdown();
		while(1);
	}

	arch_kclear();
	arch_ksetcl(0x09);
	printf("* %s %s (rev %s on %s)\n", NAME, RELEASE_NAME, REVISION, ARCH);
	arch_ksetcl(0x0F);
	puts("loading...\n");
	
	/* mem initialization */
	printf("mm init, %s\n", ((!mm_init(arch_mem_total())) ? "done" : "fail"));
	
	/* driver and device initialization */
	#ifdef DRV
		drv_init();
	#endif
	#ifdef DEV
		dev_init();
		printf("probing devices... ");
		printf("%d added (", dev_probe());
		
		dev_t *d = devlist;
		int i = 0;
		while(d != NULL)
		{
			printf("%s", d->name);
			d = d->next;
			if(d != NULL)
				printf(", ");
			i++;
		}
		printf(")\n");
	#endif
		
	/* vfs creation */
	#ifdef VFS
		printf("vfs init, %s\n", ((!vfs_init()) ? "done" : "fail"));
		printf("mounting /, %s\n", ((!vfs_mount("mm", "/", "tmpfs", NULL)) ? "done" : "fail" ));
	#endif
	

	#ifdef SMP
		if(cpu_num() > 1)
		{
			int i;
			for(i = 0; i < cpu_num(); i++)
			{
				if(cpu_whake(i))
					printf("cpu%d ", i);
			}
			printf(": ready\n");
		}
	#endif


	/* do something */
	switch(arch_info.video_mode)
	{ 
		#ifdef PORK_GUI
		case VIDEO_MODE_GRAPH:
				pork_gui(640, 480);
			break;
		#endif
			
		#ifdef SHELL
		default:
			shell();
			break;
		#endif
	}
	
	
	shutdown(1);
	
	return 0;
}	



/* shutdown and reboot */
void shutdown(int type)
{	
	int i;

	arch_ksetcl(12);
	printf("\nthe system is going down...\n");	
	arch_ksetcl(0x0F);
	
	/* umount all fs */
	#ifndef NO_VFS
		i = 0;
		mount_point_t *m;
	
		while((m = mountpoint_iget(i)) != NULL)
		{
			printf("umounting %s\n", m->path);
			vfs_umount(m->path);
			i++;
		}
	#endif
	
	switch(type)
	{
		case 1:
			arch_shutdown();
			break;
		case 2:
			arch_reboot();
			break;
	}
	while(1);
}


